package com.siashan.unipay4j.ali.pay;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.request.AlipayTradeCancelRequest;
import com.alipay.api.response.AlipayTradeCancelResponse;
import com.siashan.unipay4j.ali.AbstractAliPay;
import com.siashan.unipay4j.core.pay.CancelResponse;
import com.siashan.unipay4j.core.pay.PayCancelModel;
import com.siashan.unipay4j.core.pay.ICancel;
import com.siashan.unipay4j.core.IPayConfig;
import com.siashan.unipay4j.core.Result;
import com.siashan.unipay4j.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

/**
 * 支付宝交易撤销
 *
 * @author siashan
 * @since v1.0.1
 **/
@Slf4j
public class AliPayCancel extends AbstractAliPay implements ICancel {

    /**
     * 需要重试
     */
    private static final String  RETRY_Y = "Y";

    public AliPayCancel() {
    }

    public AliPayCancel(IPayConfig payConfig) {
        super(payConfig);
    }

    /**
     * 撤销操作
     *
     * @param model  撤销请求实体
     * @return 撤销结果
     */
    @Override
    public Result<CancelResponse> execCancel(PayCancelModel model) {
        log.info("AliCancel::=>订单{} 请求到达", model.getOrderNo());
        AlipayTradeCancelRequest request = new AlipayTradeCancelRequest();
        // 请求参数
        request.setBizContent(JSON.toJSONString(wrapParam(model)));
        try {
            AlipayTradeCancelResponse r = alipayClient.execute(request);
            if (r.isSuccess()) {
                return Result.tradeSuccess(wrapCancelResponse(r));
            } else {
                return Result.tradeFail(r.getSubCode(), r.getSubMsg(),wrapCancelResponse(r));
            }
        } catch (AlipayApiException e) {
            log.info("AliCancel::=>订单{} 撤销操作异常", model.getOrderNo(), e);
        }
        return Result.exception();
    }


    /**
     * 封装请求参数
     *
     * @param model  撤销请求实体
     * @return 请求参数
     */
    private Map<String, String> wrapParam(PayCancelModel model) {
        Map<String, String> param = new HashMap<>(2);
        if (StrUtil.isNotEmpty(model.getTradeNo())) {
            param.put("trade_no", model.getTradeNo());
        }
        if (StrUtil.isNotEmpty(model.getOutTradeNo())) {
            param.put("out_trade_no", model.getOutTradeNo());
        }
        return param;
    }

    /**
     * 封装CancelResponse
     *
     * @param r AlipayTradeCancelResponse
     * @return CancelResponse
     */
    private CancelResponse wrapCancelResponse(AlipayTradeCancelResponse r){
        CancelResponse response = new CancelResponse();
        response.setNeedRecall(RETRY_Y.equals(r.getRetryFlag()));
        response.setBody(r);
        return response;
    }
}
